<template>
  <div id="map"></div>
</template>

<script>
import mapboxgl from 'mapbox-gl'
import bus from '@/utils/bus.js'
import * as mapv from 'mapv'
import { MapvLayer } from '@supermap/iclient-mapboxgl'
import { GetFeaturesByBufferParameters, FeatureService } from '@supermap/iclient-mapboxgl'

export default {
  name: 'MapView',
  data() {
    return {
      dataUrl: '/data-SiChuan/rest/data',
      chengduMapUrl: '/map-SiChuan/restjsr/v1/vectortile/maps/SiChuanMap3857/style.json',
      jingdianDataUrl: '/data-SiChuan/rest/data/featureResults.geojson?returnContent=true',
      pathAnalysisUrl: '/transportationAnalyst-SiChuan/rest/networkanalyst/SiChuan_Network@SiChuan/path.rjson?nodes=[2,3]&parameter={"resultSetting":{"returnRoutes":true,"returnPathGuides":false}}',
      queryOption: {
        getFeatureMode: 'SQL',
        datasetNames: ['SiChuan:A级旅游景区名录'],
        maxFeatures: 2000,
        queryParameter: {
          sortClause: null,
          ids: null,
          name: null,
          attributeFilter: 'SMID>0',
          groupClause: null,
          linkItems: null,
          joinItems: null,
          fields: null
        }
      },
      jingdianNumDataOption: {
        getFeatureMode: 'SQL',
        datasetNames: ['SiChuan:州市景点数量点'],
        maxFeatures: 2000,
        queryParameter: {
          sortClause: null,
          ids: null,
          name: null,
          attributeFilter: 'SMID>0',
          groupClause: null,
          linkItems: null,
          joinItems: null,
          fields: null,
          mapVLayer: {},
          hasMapvLayer: false
        }
      },
      // 天地图矢量地图source
      tdtVec: {
        type: 'raster',
        tiles: ['http://t0.tianditu.gov.cn/vec_w/wmts?tk=1d109683f4d84198e37a38c442d68311&SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=vec&STYLE=default&TILEMATRIXSET=w&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&FORMAT=tiles'],
        tileSize: 256
      },
      // 天地图矢量注记地图source
      tdtCva: {
        type: 'raster',
        tiles: ['http://t0.tianditu.gov.cn/cva_w/wmts?tk=1d109683f4d84198e37a38c442d68311&SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=cva&STYLE=default&TILEMATRIXSET=w&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&FORMAT=tiles'],
        tileSize: 256
      },
      // 天地图影像地图source
      tduImg: {
        type: 'raster',
        tiles: ['http://t0.tianditu.gov.cn/img_w/wmts?tk=1d109683f4d84198e37a38c442d68311&SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=img&STYLE=default&TILEMATRIXSET=w&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&FORMAT=tiles'],
        tileSize: 256
      },
      // 天地图影像注记地图source
      tdtCia: {
        type: 'raster',
        tiles: ['http://t0.tianditu.gov.cn/cia_w/wmts?tk=1d109683f4d84198e37a38c442d68311&SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=cia&STYLE=default&TILEMATRIXSET=w&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&FORMAT=tiles'],
        tileSize: 256
      },
      // 天地图地形地图source
      tduTer: {
        type: 'raster',
        tiles: ['http://t0.tianditu.gov.cn/ter_w/wmts?tk=1d109683f4d84198e37a38c442d68311&SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=ter&STYLE=default&TILEMATRIXSET=w&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&FORMAT=tiles'],
        tileSize: 256
      },
      // 天地图地形注记地图source
      tdtCta: {
        type: 'raster',
        tiles: ['http://t0.tianditu.gov.cn/cta_w/wmts?tk=1d109683f4d84198e37a38c442d68311&SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=cta&STYLE=default&TILEMATRIXSET=w&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&FORMAT=tiles'],
        tileSize: 256
      },
      sichuangMap: '',
      send: {
        name: '',
        leavel: '',
        address: ''
      },
      flag: false,
      markers: {},
      jingdianData: {},
      jingdianMarkers: {},
      flag1: false,
      markerStatus: false,
      wantToJingdianMarkers: {},
      wantToJingdianStatus: false
    }
  },
  created() {
    bus.$on('addTiandituVec', () => {
      this._addTiandituVec()
    })
    bus.$on('addTiandituImg', () => {
      this._addTiandituImg()
    })
    bus.$on('addTiandituTer', () => {
      this._addTiandituTer()
    })
    bus.$on('addRelitu', () => {
      this._addRelitu()
    })
    bus.$on('removeAllLayer', () => {
      this._removeAllLayer()
    })
    bus.$on('addJuhetu', () => {
      this._addJuhetu()
    })
    bus.$on('addFengchaotu', () => {
      this._addFengchaotu()
    })
    bus.$on('addMarker', () => {
      this._addMarker()
    })
    bus.$on('removeMarker', () => {
      this._removeMarker()
    })
    bus.$on('zoomToMarker', () => {
      this._zoomToMarker()
    })
    bus.$on('changeMarkerStatus', () => {
      this._changeMarkerStatus()
    })
    bus.$on('setMarkerStatus', () => {
      this._setMarkerStatus()
    })
    bus.$on('zoomToPoint', e => {
      this._zoomToPoint(e)
    })
    bus.$on('removeWantToJingdianMarkers', () => {
      this._removeWantToJingdianMarkers()
    })
    bus.$on('getPath', () => {
      this._getPath()
    })
  },
  mounted() {
    this._getChengduMap()
    this._getJingdianData()

    this.$map = new mapboxgl.Map({
      container: 'map',
      renderWorldCopies: false,
      style: {
        version: 8,
        sources: {
          tdtVec: this.tdtVec,
          tdtCva: this.tdtCva,
          tduImg: this.tduImg,
          tdtCia: this.tdtCia,
          tduTer: this.tduTer,
          tdtCta: this.tdtCta
        },
        layers: [
          {
            id: 'tdtVec',
            type: 'raster',
            source: 'tdtVec',
            minzoom: 0,
            maxzoom: 22
          },
          {
            id: 'tdtCva',
            type: 'raster',
            source: 'tdtCva',
            minzoom: 0,
            maxzoom: 22
          }
        ]
      },
      pitch: 90,
      bearing: 0,
      altitudeScale: 0,
      center: [102.85, 30.66],
      zoom: 6
    })

    this.$map.on('load', () => {
      this.$map.addStyle(this.sichuangMap)

      this._clickQueryJingdian()
    })
  },
  methods: {
    _clickQueryJingdian() {
      console.log(this.$map.getStyle().layers)
      this.$map.on('click', e => {
        if (this.flag) {
          this.markers.remove()
          this.flag = !this.flag
        }

        let queryBufferGeometry = {
          type: 'Feature',
          geometry: {
            type: 'Point',
            coordinates: [e.lngLat.lng, e.lngLat.lat]
          }
        }

        var bufferParam = new GetFeaturesByBufferParameters({
          datasetNames: ['SiChuan:A级旅游景区名录'],
          bufferDistance: 0.01,
          geometry: queryBufferGeometry
          // targetPrj: { epsgCode: 3857 }
        })
        new FeatureService(this.$http.defaults.baseURL + this.dataUrl).getFeaturesByBuffer(bufferParam, serviceResult => {
          if (!this.flag) {
            if (serviceResult.result.features.features.length !== 0) {
              this.markers = new mapboxgl.Marker().setLngLat(serviceResult.result.features.features[0].geometry.coordinates).addTo(this.$map)
              this.flag = !this.flag

              this.send.name = serviceResult.result.features.features[0].properties.名称
              this.send.leavel = serviceResult.result.features.features[0].properties.等级
              this.send.address = serviceResult.result.features.features[0].properties.地址
            }
          }

          bus.$emit('queryData', this.send)
        })
      })
    },
    async _getChengduMap() {
      const { data: res } = await this.$http.get(this.chengduMapUrl)
      if (res !== {}) {
        this.sichuangMap = res
      }
    },
    _addTiandituVec() {
      // 移除影像天地图
      if (this.$map.getLayer('tduImg')) {
        this.$map.removeLayer('tduImg')
      }
      if (this.$map.getLayer('tdtCia')) {
        this.$map.removeLayer('tdtCia')
      }

      // 移除地形天地图
      if (this.$map.getLayer('tduTer')) {
        this.$map.removeLayer('tduTer')
      }
      if (this.$map.getLayer('tdtCta')) {
        this.$map.removeLayer('tdtCta')
      }

      if (this.$map.getLayer('tdtVec') && this.$map.getLayer('tdtCva')) {
        return
      } else {
        this.$map.addLayer(
          {
            id: 'tdtVec',
            type: 'raster',
            source: 'tdtVec',
            minzoom: 0,
            maxzoom: 22
          },
          'A级旅游景区名录_3857@SiChuan#1(12_24)'
        )
        this.$map.addLayer(
          {
            id: 'tdtCva',
            type: 'raster',
            source: 'tdtCva',
            minzoom: 0,
            maxzoom: 22
          },
          'A级旅游景区名录_3857@SiChuan#1(12_24)'
        )
      }
    },
    _addTiandituImg() {
      // 移除矢量天地图
      if (this.$map.getLayer('tdtVec')) {
        this.$map.removeLayer('tdtVec')
      }
      if (this.$map.getLayer('tdtCva')) {
        this.$map.removeLayer('tdtCva')
      }

      // 移除地形天地图
      if (this.$map.getLayer('tduTer')) {
        this.$map.removeLayer('tduTer')
      }
      if (this.$map.getLayer('tdtCta')) {
        this.$map.removeLayer('tdtCta')
      }

      if (this.$map.getLayer('tduImg') && this.$map.getLayer('tdtCia')) {
        return
      } else {
        this.$map.addLayer(
          {
            id: 'tduImg',
            type: 'raster',
            source: 'tduImg',
            minzoom: 0,
            maxzoom: 22
          },
          'A级旅游景区名录_3857@SiChuan#1(12_24)'
        )
        this.$map.addLayer(
          {
            id: 'tdtCia',
            type: 'raster',
            source: 'tdtCia',
            minzoom: 0,
            maxzoom: 22
          },
          'A级旅游景区名录_3857@SiChuan#1(12_24)'
        )
      }
    },
    _addTiandituTer() {
      // 移除矢量天地图
      if (this.$map.getLayer('tdtVec')) {
        this.$map.removeLayer('tdtVec')
      }
      if (this.$map.getLayer('tdtCva')) {
        this.$map.removeLayer('tdtCva')
      }

      // 移除影像天地图
      if (this.$map.getLayer('tduImg')) {
        this.$map.removeLayer('tduImg')
      }
      if (this.$map.getLayer('tdtCia')) {
        this.$map.removeLayer('tdtCia')
      }

      if (this.$map.getLayer('tduTer') && this.$map.getLayer('tdtCta')) {
        return
      } else {
        this.$map.addLayer(
          {
            id: 'tduTer',
            type: 'raster',
            source: 'tduTer',
            minzoom: 0,
            maxzoom: 22
          },
          'A级旅游景区名录_3857@SiChuan#1(12_24)'
        )
        this.$map.addLayer(
          {
            id: 'tdtCta',
            type: 'raster',
            source: 'tdtCta',
            minzoom: 0,
            maxzoom: 22
          },
          'A级旅游景区名录_3857@SiChuan#1(12_24)'
        )
      }
    },
    async _getJingdianData() {
      const { data: res } = await this.$http.post(this.jingdianDataUrl, this.queryOption)

      this.jingdianData = res
    },
    _removeAllLayer() {
      if (this.$map.getLayer('heatmap')) {
        this.$map.removeLayer('heatmap')
        this.$map.removeSource('heatmap')
      }

      if (this.$map.getLayer('clusters')) {
        this.$map.removeLayer('clusters')
      }

      if (this.$map.getLayer('cluster-count')) {
        this.$map.removeLayer('cluster-count')
      }

      if (this.$map.getLayer('unclustered-point')) {
        this.$map.removeLayer('unclustered-point')
        this.$map.removeSource('earthquakes')
      }

      if (this.hasMapvLayer) {
        this.hasMapvLayer = !this.hasMapvLayer
        this.mapVLayer.onRemove()
      }
    },
    _addRelitu() {
      this._removeAllLayer()

      let heatPoints = {
        type: 'FeatureCollection',
        features: this.jingdianData.features
      }

      this.$map.addSource('heatmap', {
        type: 'geojson',
        data: heatPoints
      })

      // 判断添加热力图在什么图层之上
      let uplayer = ''
      if (this.$map.getLayer('tdtCva')) {
        uplayer = 'tdtCva'
      }
      if (this.$map.getLayer('tdtCia')) {
        uplayer = 'tdtCia'
      }
      if (this.$map.getLayer('tdtCta')) {
        uplayer = 'tdtCta'
      }

      this.$map.addLayer(
        {
          id: 'heatmap',
          type: 'heatmap',
          source: 'heatmap',
          paint: {
            'heatmap-weight': 1,
            'heatmap-intensity': 2,
            'heatmap-color': ['interpolate', ['linear'], ['heatmap-density'], 0, 'rgba(33,102,172,0)', 0.2, 'rgb(103,169,207)', 0.4, 'rgb(209,229,240)', 0.6, 'rgb(253,219,199)', 0.8, 'rgb(239,138,98)', 1, 'rgb(178,24,43)'],
            'heatmap-radius': 50
          }
        },
        uplayer
      )
    },
    _addJuhetu() {
      this._removeAllLayer()

      let jingdianData = {
        type: 'FeatureCollection',
        features: this.jingdianData.features
      }

      this.$map.addSource('earthquakes', {
        type: 'geojson',
        data: jingdianData,
        cluster: true,
        clusterMaxZoom: 14,
        clusterRadius: 100
      })

      this.$map.addLayer({
        id: 'clusters',
        type: 'circle',
        source: 'earthquakes',
        filter: ['has', 'point_count'],
        paint: {
          'circle-color': ['step', ['get', 'point_count'], '#51bbd6', 100, '#f1f075', 750, '#f28cb1'],
          'circle-radius': ['step', ['get', 'point_count'], 20, 100, 30, 750, 40]
        }
      })

      this.$map.addLayer({
        id: 'cluster-count',
        type: 'symbol',
        source: 'earthquakes',
        filter: ['has', 'point_count'],
        layout: {
          'text-field': '{point_count_abbreviated}',
          'text-font': ['DIN Offc Pro Medium', 'Arial Unicode MS Bold'],
          'text-size': 12
        }
      })

      this.$map.addLayer({
        id: 'unclustered-point',
        type: 'circle',
        source: 'earthquakes',
        filter: ['!', ['has', 'point_count']],
        paint: {
          'circle-color': '#11b4da',
          'circle-radius': 4,
          'circle-stroke-width': 1,
          'circle-stroke-color': '#fff'
        }
      })
    },
    async _addFengchaotu() {
      this._removeAllLayer()

      const { data: res } = await this.$http.post(this.jingdianDataUrl, this.jingdianNumDataOption)
      let resData = res.features
      resData.shift()

      let newData = resData.map(function (feature) {
        return {
          geometry: {
            type: feature.geometry.type,
            coordinates: feature.geometry.coordinates
          },
          count: Number(feature.properties['总计'])
        }
      })

      const dataSet = new mapv.DataSet(newData)

      let options = {
        fillStyle: 'rgba(55, 50, 250, 0.8)',
        shadowColor: 'rgba(255, 250, 50, 1)',
        shadowBlur: 20,
        max: 100,
        size: 50,
        unit: 'px', // unit可选值['px', 'm']，默认值为'px'
        label: {
          show: true,
          fillStyle: 'white'
        },
        globalAlpha: 0.5,
        gradient: { 0.25: 'rgb(0,0,255)', 0.55: 'rgb(0,255,0)', 0.85: 'yellow', 1.0: 'rgb(255,0,0)' },
        draw: 'honeycomb'
      }

      if (!this.hasMapvLayer) {
        //创建MapV图层
        this.mapVLayer = new MapvLayer(dataSet, options)
        this.hasMapvLayer = !this.hasMapvLayer
        this.$map.addLayer(this.mapVLayer)
      }
    },
    _addMarker() {
      this.$map.on('click', e => {
        if (this.flag1) {
          this.jingdianMarkers.remove()
          this.flag1 = !this.flag1
        }

        if (!this.flag1) {
          if (this.markerStatus) {
            this.jingdianMarkers = new mapboxgl.Marker({ color: 'red' }).setLngLat(e.lngLat).addTo(this.$map)
            this.flag1 = !this.flag1
          }
        }
      })
    },
    _removeMarker() {
      if (this.flag1) {
        this.jingdianMarkers.remove()
        this.flag1 = !this.flag1
      }

      if (this.flag) {
        this.markers.remove()
        this.wantToJingdianMarkers.remove()
        this.flag = !this.flag
      }
    },
    _removeWantToJingdianMarkers() {
      if (this.wantToJingdianStatus) {
        this.wantToJingdianMarkers.remove()
        this.wantToJingdianStatus = !this.wantToJingdianStatus
      }

      if (this.$map.getLayer('pathDatas')) {
        this.$map.removeLayer('pathDatas')
      }
      if (this.$map.getSource('pathDatas')) {
        this.$map.removeSource('pathDatas')
      }
    },
    _zoomToMarker() {
      this.$map.flyTo({
        center: this.jingdianMarkers.getLngLat(),
        zoom: 13
      })
    },
    _changeMarkerStatus() {
      this.markerStatus = !this.markerStatus
    },
    _setMarkerStatus() {
      this.markerStatus = false
    },
    _zoomToPoint(e) {
      // this._removeMarker()
      this.$map.flyTo({
        center: e,
        zoom: 13
      })

      if (!this.wantToJingdianStatus) {
        this.wantToJingdianMarkers = new mapboxgl.Marker({ color: 'blue' }).setLngLat(e).addTo(this.$map)
        this.wantToJingdianStatus = !this.wantToJingdianStatus
      }
    },
    async _getPath() {
      if (this.markerStatus && this.wantToJingdianStatus) {
        this.pathAnalysisUrl = `${this.$http.defaults.baseURL}/transportationAnalyst-SiChuan/rest/networkanalyst/SiChuan_Network@SiChuan/path.rjson?nodes=[{"x":${this.jingdianMarkers.getLngLat().lng},"y":${this.jingdianMarkers.getLngLat().lat}} ,{"x":${
          this.wantToJingdianMarkers.getLngLat().lng
        },"y":${this.wantToJingdianMarkers.getLngLat().lat}}]&parameter={"resultSetting":{"returnRoutes":true,"returnPathGuides":false}}`
        const { data: res } = await this.$http.get(this.pathAnalysisUrl)

        const pathGeojson = {
          type: 'FeatureCollection',
          features: [
            {
              type: 'Feature',
              geometry: {
                type: 'LineString',
                coordinates: res.pathList[0].route.line.points.map(point => [point.x, point.y])
              },
              properties: {
                length: res.pathList[0].route.length,
                id: res.pathList[0].route.id,
                center: res.pathList[0].route.line.center,
                parts: res.pathList[0].route.line.parts,
                maxM: res.pathList[0].route.maxM,
                minM: res.pathList[0].route.minM,
                style: res.pathList[0].route.line.style,
                prjCoordSys: res.pathList[0].route.line.prjCoordSys,
                type: res.pathList[0].route.type,
                partTopo: res.pathList[0].route.partTopo
              }
            }
          ]
        }

        bus.$emit('pathLength', res.pathList[0].route.length)

        if (this.$map.getLayer('pathDatas')) {
          this.$map.removeLayer('pathDatas')
        }
        if (this.$map.getSource('pathDatas')) {
          this.$map.removeSource('pathDatas')
        }

        this.$map.addSource('pathDatas', {
          type: 'geojson',
          data: pathGeojson
        })
        this.$map.addLayer({
          id: 'pathDatas',
          type: 'line',
          source: 'pathDatas',
          layout: {},
          paint: {
            'line-color': '#FF0000',
            'line-opacity': 1,
            'line-width': 5
          }
        })
      } else {
        this.$message({
          message: '请先添加出发点与旅游目的地！',
          type: 'warning'
        })
      }
    }
  }
}
</script>

<style lang="less" scoped>
#map {
  margin: 0;
  padding: 0;
  overflow: hidden;
  background: #fff;
  width: 100%;
  height: 100%;
  position: absolute;
}
.btn {
  position: absolute;
  top: 20px;
  left: 60px;
  z-index: 999;
}
body {
  margin: 0;
  padding: 0;
}
.changeMap {
  z-index: 9;
  position: absolute;
  // background-color: red;
  width: 300px;
  height: 200px;
  right: 40px;
  bottom: 50px;
}

.panel {
  position: relative;
  border: 15px solid transparent;
  border-width: 0.6375rem 0.475rem 0.25rem 1.65rem;
  border-image-source: url(../../assets/images/border.png);
  border-image-slice: 51 38 20 132;
  margin-bottom: 20px;
  z-index: 9;
  position: absolute;
  // background-color: red;
  width: 300px;
  height: 200px;
  right: 40px;
  bottom: 50px;
}

.order {
  height: 1.875rem;
}

.order .filter {
  display: flex;
}

.order .filter a {
  display: block;
  height: 0.225rem;
  line-height: 1;
  padding: 0 0.225rem;
  color: #1950c4;
  font-size: 0.225rem;
  border-right: 0.025rem solid #00f2f1;
}

.order .filter a:first-child {
  padding-left: 0;
}

.order .filter a:last-child {
  border-right: none;
}

.order .filter a.active {
  color: #fff;
  font-size: 0.25rem;
}

.order .data {
  display: flex;
  margin-top: 0.25rem;
}

.order .item {
  width: 50%;
}

.order h4 {
  font-size: 0.35rem;
  color: #fff;
  margin-bottom: 0.125rem;
}

.order span {
  display: block;
  color: #4c9bfd;
  font-size: 0.2rem;
}
</style>
